package cn.wen.yinxiu.member.service.impl;

import cn.wen.yinxiu.common.enums.DelEnum;
import cn.wen.yinxiu.common.enums.StatusEnum;
import cn.wen.yinxiu.member.dao.UsersDao;
import cn.wen.yinxiu.member.entity.UsersEntity;
import cn.wen.yinxiu.member.vo.ChatRecordInfo;
import cn.wen.yinxiu.member.vo.ChatRecordVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.wen.yinxiu.common.toolkit.PageUtils;
import cn.wen.yinxiu.common.toolkit.Query;

import cn.wen.yinxiu.member.dao.ChatRecordDao;
import cn.wen.yinxiu.member.entity.ChatRecordEntity;
import cn.wen.yinxiu.member.service.ChatRecordService;

import static cn.wen.yinxiu.common.constant.Constant.TalkType.Friend;
import static cn.wen.yinxiu.common.constant.Constant.TalkType.Group;


@Component
@Service("chatRecordService")
public class ChatRecordServiceImpl extends ServiceImpl<ChatRecordDao, ChatRecordEntity> implements ChatRecordService {

    @Value("${yinxiu.chat.pageSize}")
    private Integer pageSize;

    @Autowired
    private ChatRecordDao chatRecordDao;

    @Autowired
    private UsersDao usersDao;

    @Autowired
    private ThreadPoolExecutor executor;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<ChatRecordEntity> page = this.page(
                new Query<ChatRecordEntity>().getPage(params),
                new QueryWrapper<ChatRecordEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void appendChatRecord(ChatRecordEntity chatRecord) {
        chatRecord.setMsgTime(new Date());
        chatRecord.setStatus(StatusEnum.NORMAL_USE.code());
        chatRecord.setIsDeleted(DelEnum.NORMAL.code());
        CompletableFuture.runAsync(() -> {
            // 插入数据
            chatRecordDao.insert(chatRecord);
        }, executor);
    }

    @Override
    public List<ChatRecordEntity> queryUserChatRecordList(Long talkId, Long userId, Integer page) {
        QueryWrapper<ChatRecordEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("talk_type", Friend.getCode());
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        queryWrapper.eq("status", StatusEnum.NORMAL_USE.code());
        queryWrapper.and(wrapper -> wrapper.and(o -> o.eq("friend_id", talkId).eq("user_id", userId))
                .or(o -> o.eq("friend_id", userId).eq("user_id", talkId)));
        queryWrapper.orderByAsc("create_time");
        queryWrapper.last("LIMIT " + pageSize * (page - 1) + "," + pageSize);
        return chatRecordDao.selectList(queryWrapper);
    }

    @Override
    public List<ChatRecordEntity> queryGroupsChatRecordList(Long talkId, Integer page) {
        QueryWrapper<ChatRecordEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("talk_type", Group.getCode());
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        queryWrapper.eq("status", StatusEnum.NORMAL_USE.code());
        queryWrapper.eq("friend_id", talkId);
        queryWrapper.orderByDesc("create_time");
        queryWrapper.last("LIMIT " + pageSize * (page - 1) + "," + pageSize);
        return chatRecordDao.selectList(queryWrapper);
    }

    @Override
    public List<ChatRecordVO> queryChatRecordVOList(Long talkId, Long userId, Integer talkType, Integer page) {
        List<ChatRecordVO> chatRecordVOList = new ArrayList<>();
        List<ChatRecordEntity> list;
        if (Friend.getCode().equals(talkType)){
            list = queryUserChatRecordList(talkId, userId, page);
            for (ChatRecordEntity entity : list) {
                ChatRecordVO chatRecordVO = new ChatRecordVO();
                chatRecordVO.setTalkId(talkId);
                boolean msgType = userId == entity.getUserId();
                // 自己发的消息
                if (msgType) {
                    chatRecordVO.setUserId(entity.getUserId());
                    chatRecordVO.setMsgUserType(0); // 消息类型[0自己/1好友]
                }
                // 好友发的消息
                else {
                    chatRecordVO.setUserId(entity.getFriendId());
                    chatRecordVO.setMsgUserType(1); // 消息类型[0自己/1好友]
                    // 获取用户的信息
                    UsersEntity friendInfo = usersDao.selectById(entity.getFriendId());
                    chatRecordVO.setUserNickName(friendInfo.getUsername());
                    chatRecordVO.setUserAvatar(friendInfo.getAvatar());
                }
                chatRecordVO.setMsgContent(entity.getMessage());
                chatRecordVO.setMsgType(entity.getMsgType());
                chatRecordVO.setMsgTime(entity.getMsgTime());
                chatRecordVOList.add(chatRecordVO);
            }
        } else if (Group.getCode().equals(talkType)){
            list = queryGroupsChatRecordList(talkId, page);
            for (ChatRecordEntity chatRecordInfo : list) {
                UsersEntity usersEntity = usersDao.selectById(chatRecordInfo.getUserId());
                ChatRecordVO ChatRecordVO = new ChatRecordVO();
                // 群组ID
                ChatRecordVO.setTalkId(talkId);
                ChatRecordVO.setUserId(usersEntity.getId());
                ChatRecordVO.setUserNickName(usersEntity.getUsername());
                ChatRecordVO.setUserAvatar(usersEntity.getAvatar());
                ChatRecordVO.setMsgContent(chatRecordInfo.getMessage());
                ChatRecordVO.setMsgTime(chatRecordInfo.getMsgTime());
                boolean msgType = usersEntity.getId() == chatRecordInfo.getUserId();
                ChatRecordVO.setMsgUserType(msgType ? 0 : 1); // 消息类型[0自己/1好友]
                ChatRecordVO.setMsgType(chatRecordInfo.getMsgType());
                chatRecordVOList.add(ChatRecordVO);
            }
        }
        return chatRecordVOList;

    }

}